package com.dean.listener;

import com.alibaba.excel.context.AnalysisContext;
import com.alibaba.excel.event.AnalysisEventListener;
import com.alibaba.excel.exception.ExcelCommonException;
import com.dean.entity.DeanDbConnInfo;
import com.dean.entity.DeanImportInfo;
import com.dean.entity.SysDbConnInfo;
import com.dean.utils.DeanJdbcUtils;
import com.dean.utils.DeanSqlUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
 * @ClassName DeanEasyExcelListener
 * @Description excel 导入监听
 * @Author dean
 * @Date 2021/10/3 10:03
 */
public class DeanEasyExcelListener extends AnalysisEventListener<Map<Integer,String>>{

	private static final Logger logger = LoggerFactory.getLogger(DeanEasyExcelListener.class);
	
	/**
	 * excel 头信息
	 */
	private  List<Integer> head = new ArrayList<>();
	/**
	 * excel 数据信息
	 */
	private List<List<String>> datas = new ArrayList<List<String>>();

	/**
	 * 导入配置信息
	 */
	private DeanImportInfo importInfo;

	/**
	 * 执行sql
	 */
	private String insertSql;


	public void setImportInfo(DeanImportInfo importInfo) {
		this.importInfo = importInfo;
		this.insertSql = DeanSqlUtils.createInsertSql(importInfo.getTableName(),importInfo.getFields());
	}

	/**
	 * 数据库连接配置信息
	 */
	private SysDbConnInfo connInfo;

	public void setConnInfo(SysDbConnInfo connInfo){
		this.connInfo = connInfo;
	}


	/**
	 * excel 提交数量统计
	 */
	private int commitCounts = 0;


	/**
	 * 备注字段
	 */
	private String remark;

	public void setRemark(String remark) {
		this.remark = remark;
	}

	/**
	 * 单个sheet 页的总数量
	 */
	private int totalCounts=0;

	/**
	 * 表头处理
	 * 如果用户指定的表头信息 在 文件的表头 全都找到了 则进行数据导入 否则 不处理
	 *
	 */
	@Override
	public void invokeHeadMap(Map<Integer, String> headMap, AnalysisContext context) {
		Map<String,Integer> headMapCovert = new HashMap<String,Integer>(headMap.size());
		//将key value 反转
		headMap.forEach((key,val)->{
			headMapCovert.put(val.toUpperCase(),key);
		});
		head.clear();
		String[] fileds =importInfo.getFields();
		logger.info("用户指定表头:{}",fileds);
		logger.info("文件读取到表头{}:",headMap);
		for (String filed : fileds) {
			if(headMapCovert.containsKey(filed.toUpperCase()) && !filed.contains("=")){
				head.add(headMapCovert.get(filed.toUpperCase()));
			}
		}
		logger.info("用户指定表头与文件表头映射:{}",head);
		if(this.head.size()!=fileds.length) {
			throw new ExcelCommonException("ERROR-表头列匹配不成功");
		}
	}

	@Override
	public void invoke(Map<Integer,String> data, AnalysisContext context) {
		List<String> record = new ArrayList<String>(head.size());
		for (Integer integer : head) {
			record.add(data.get(integer));
		}
		datas.add(record);
		commitCounts++;
		if(commitCounts == importInfo.getCommitNums()) {
			totalCounts += commitCounts;
			if(!saveDb()){
				return;
			};
			logger.debug("current data has been saved saved counts is {}",commitCounts);
		}	
	}

	@Override
	public void doAfterAllAnalysed(AnalysisContext context) {
		if(commitCounts > 0) {
			totalCounts += commitCounts;
			if(!saveDb()){
				return;
			};
		}
		// TODO Auto-generated method stub
		logger.debug("all data has been read total size is:{}",totalCounts);
	}

	/**
	 * 进行数据插入
	 * @return
	 */
	private boolean saveDb() {
		DeanJdbcUtils.batchInsert(this.connInfo,this.insertSql,this.datas,this.remark);
		// 数据清零重新统计
		datas.clear();
		commitCounts=0;
		return true;
	}

}
